﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BLToolkit.Aspects;
using BLToolkit.Data;
using BLToolkit.DataAccess;
using BLToolkit.EditableObjects;
using BLToolkit.Mapping;
using BLToolkit.Reflection;
using BLToolkit.Reflection.Extension;
using BLToolkit.TypeBuilder;
using Devsoft.DB.Models;
using Devsoft.DB.Models.EditableObject;

namespace Devsoft.DB.Models.EditableObject
{
    [Serializable]
    public class ModelWithManager<T, TManager> : BaseModel<T>
        where T : ModelWithManager<T, TManager>
        where TManager : Manager<T>
    {

        #region Model Operations

        public override void Save()
        {
            InsertOrUpdate();
        }

        public override void Delete()
        {
            Objects.Delete(this as T);
        }

        public override void Remove()
        {
            this.Delete();
        }

        public override void Insert(bool forceInsert = false)
        {
            if (IsDirty || forceInsert)
            {
                if (!forceInsert && !IsNew)
                {
                    throw new Exception("Already inserted. To force insert, use x.Insert(true)");
                }
                AcceptChanges();
                object id = Objects.InsertWithIdentity(this as T);
                UpdateInsertedIdentity(id);
            }
        }

        public override bool Update(bool forceUpdate = false)
        {
            if (IsDirty || forceUpdate)
            {
                if (Objects.Update(this as T))
                {
                    AcceptChanges();
                    return true;
                };
            }
            return false;
        }

        public override void InsertOrUpdate()
        {
            if (IsNew)
            {
                Insert(true);
            }
            else
            {
                Update();
            }
        }
        
        #endregion

        #region Table Operations

        public static TManager Objects
        {
            get
            {
                /*
                if (_Objects == null)
                {
                    _Objects = CreateMaganger();
                }
                return _Objects;
                 * */
                return CreateMaganger();
            }
        }

        #endregion

        #region Protected Methods

        protected static TManager CreateMaganger()
        {
            //return Activator.CreateInstance(typeof(TManager), DataContextFactory.GetScopedDataContext<DbManager>()) as TManager;
            var t = TypeFactory.GetType(typeof(TManager));
            return Activator.CreateInstance(t, DataContextFactory.GetScopedDataContext<DbManager>(typeof(T))) as TManager;
        }

        #endregion
        
    }
}
